/*
 * energy_calc.h
 *
 *  Created on: Feb 17, 2010
 *      Author: snirgaz
 */

#ifndef ENERGY_CALC_H_
#define ENERGY_CALC_H_

#include "HelpLibs/def.h"
#include "WorldLines.h"
#include "ParticlePos.h"
#include "MoveParams.h"
#include "HelpLibs/QmcParameters.h"
#include <tr1/functional>

#ifdef POT_AZIZ
void calcGreenForce(ParticlePos & dr, double rZero, double &v, double &f);
void calcGreen(ParticlePos & dr, double rZero, double &v);
#endif

typedef vector<BeadVec::iterator> BeadIterVec;

class EnergyCalc {
	class CalcGreen {
	private:
		static double drZero_;
	public:
		void init(double drZero);
		static void calcGreen(ParticlePos const &dr,double &v);
		static void calcGreenForce(ParticlePos const &dr,double &v,double &f);
	};
private:
	// Forces Temporary
	ForceData resFProposed_, resFOriginal_;
	// Jump Forces Temporary
	ForceSlice resFProposedJump_, resFOriginalJump_;
	MoveParams *moveParams_;
	QmcParameters *qmcParameters_;
	WorldLines *wl_;
	double greenFac_, forceFac_;
	EnergyData energyOriginal_, energyProposed_;
	int numP_;

	// Array for calculations,
public:
	EnergyCalc();
	~EnergyCalc();
	// Initialization
	void init(QmcParameters *qmcParameters, WorldLines *wl);
	// Energy Calculations
	EnergyData calcBeadsEnergy();
	void energyCalcSingleTimeSlice(ConfSlice const & wlTimeSlice,
			ParticlePos const & testParticlePos, int testParticleN, bool isOdd,
			ForceSlice & forceTimeSlice, double &totalv);
	void energyCalcAllProposed();
	void energyCalcAllOriginal();
	double calcTotalFSingleSlice(ForceSlice const &allO, ForceSlice &allP,
			ForceSlice const &singleO, ForceSlice const & singleP,
			int particleNum);
	void calcTotalFallSlices();
	void calcTotalV();
	void countSlices();
	// Swap Energy Calculation
	void energyCalcSingleTimeSliceSwap(ConfSlice const & wlTimeSlice,
			ParticlePos const & testParticlePos,
			const ParticlePos& jumpParticlePos, int swapToWL, int originalWL,
			bool isOdd, ForceSlice & forceTimeSlice, double &totalv);
	void arrangeDataSwap(int originalWL, int swapWL);
	EnergyData calcEnergySwap(int originalWL, int swapWL);
	// Shift Energy Calculation
	void arrangeDataShift(ParticlePos const &beadTau);
	EnergyData calcEnergyShift(ParticlePos const &beadTau);
	// Calculates Total configuration Energy
	EnergyData calcConfigurationEnergy(bool update = false);
	void calcTotalFSwap(int wlOriginal, int wlSwap);
	void calcExtPot(BeadIterVec const &currentBeads);
	void calcExtPotSwap(int wlOriginal, int wlSwap);
	// Debug
	void test_green(int res);
	void calcTotalVSwap();
	void calcEnergyParallel();
};

#endif /* ENERGY_CALC_H_ */

